package com.mulong.common.dao.mall;

import java.util.*;
import java.util.concurrent.Callable;

import jakarta.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.mulong.common.dao.mall.mapper.BrandMapper;
import com.mulong.common.dao.mall.mapper.DeliveryTypeMapper;
import com.mulong.common.dao.mall.mapper.GatewayAccountMapper;
import com.mulong.common.dao.mall.mapper.SupplierChannelMapper;
import com.mulong.common.domain.pojo.mall.Brand;
import com.mulong.common.domain.pojo.mall.DeliveryType;
import com.mulong.common.domain.pojo.mall.SupplierChannel;
import com.mulong.common.domain.pojo.mall.custom.CustomDataDictionary;
import com.mulong.common.domain.pojo.mall.custom.GatewayAccountQuery;
import com.mulong.common.enums.AccountRechargeChannel;
import com.mulong.common.enums.AccountRechargeStatus;
import com.mulong.common.enums.AccountTransactionCategory;
import com.mulong.common.enums.CustomerOrderStatus;
import com.mulong.common.enums.GatewayAccountStatus;
import com.mulong.common.enums.GatewayAccountType;
import com.mulong.common.enums.GoodsCategory;
import com.mulong.common.enums.GoodsDemandNeedNotice;
import com.mulong.common.enums.GoodsDemandStatus;
import com.mulong.common.enums.GoodsSex;
import com.mulong.common.enums.HelpCenterRecordCategory;
import com.mulong.common.enums.HelpCenterRecordStatus;
import com.mulong.common.enums.Province;
import com.mulong.common.enums.Season;

import lombok.extern.slf4j.Slf4j;

/**
 * EnumDao
 * 
 * @author mulong
 * @data 2021-05-31 09:34:55
 */
@Slf4j
@Component
public class EnumDao {
    public static final String ENUM_GATEWAY_ACCOUNT = "GATEWAY_ACCOUNT";
    public static final String ENUM_GATEWAY_ACCOUNT_TYPE = "GATEWAY_ACCOUNT_TYPE";
    public static final String ENUM_GATEWAY_ACCOUNT_STATUS = "GATEWAY_ACCOUNT_STATUS";
    public static final String ENUM_SUPPLIER_GATEWAY_ACCOUNT = "SUPPLIER_GATEWAY_ACCOUNT";
    public static final String ENUM_HELP_CENTER_HELP_CATEGORY = "HELP_CENTER_HELP_CATEGORY";
    public static final String ENUM_HELP_CENTER_HELP_STATUS = "HELP_CENTER_HELP_STATUS";
    public static final String ENUM_GOODS_DEMAND_STATUS = "GOODS_DEMAND_STATUS";
    public static final String ENUM_GOODS_DEMAND_NEED_NOTICE = "GOODS_DEMAND_NEED_NOTICE";
    public static final String ENUM_ACCOUNT_RECHARGE_CHANNEL = "ACCOUNT_RECHARGE_CHANNEL";
    public static final String ENUM_ACCOUNT_RECHARGE_STATUS = "ACCOUNT_RECHARGE_STATUS";
    public static final String ENUM_ACCOUNT_TRANSACTION_CATRGORY = "ACCOUNT_TRANSACTION_CATRGORY";
    public static final String ENUM_PROVINCE = "PROVINCE";
    public static final String ENUM_BRAND = "BRAND";
    public static final String ENUM_SEASON = "SEASON";
    public static final String ENUM_DELIVERY_TYPE = "DELIVERY_TYPE";
    public static final String ENUM_SUPPLIER_CHANNEL = "SUPPLIER_CHANNEL";
    public static final String ENUM_GOODS_CATEGORY = "GOODS_CATEGORY";
    public static final String ENUM_GOODS_SEX = "GOODS_SEX";
    public static final String ENUM_CUSTOMER_ORDER_STATUS = "CUSTOMER_ORDER_STATUS";

    @Autowired
    private DataDictionaryDao dataDictionaryDao;
    @Autowired
    private GatewayAccountMapper gatewayAccountMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private DeliveryTypeMapper deliveryTypeMapper;
    @Autowired
    private SupplierChannelMapper supplierChannelMapper;

    private Map<String, Callable<List<?>>> getEnumByCodeHandlerMap;
    private List<GatewayAccountType> allGatewayAccountType;
    private List<GatewayAccountStatus> allGatewayAccountStatus;
    private List<HelpCenterRecordCategory> allHelpCenterRecordCategory;
    private List<HelpCenterRecordStatus> allHelpCenterRecordStatus;
    private List<GoodsDemandStatus> allGoodsDemandStatus;
    private List<GoodsDemandNeedNotice> allGoodsDemandNeedNotice;
    private List<AccountRechargeChannel> allAccountRechargeChannel;
    private List<AccountRechargeStatus> allAccountRechargeStatus;
    private List<AccountTransactionCategory> allAccountTransactionCategory;
    private List<Province> allProvince;
    private List<Season> allSeason;
    private List<GoodsCategory> allGoodsCategory;
    private List<GoodsSex> allGoodsSex;
    private List<CustomerOrderStatus> allCustomerOrderStatus;

    @PostConstruct
    public void init() {
        getEnumByCodeHandlerMap = new HashMap<>();
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GATEWAY_ACCOUNT, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return gatewayAccountMapper.selectAll();
            }
        });
        allGatewayAccountType = Arrays.asList(GatewayAccountType.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GATEWAY_ACCOUNT_TYPE, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allGatewayAccountType;
            }
        });
        allGatewayAccountStatus = Arrays.asList(GatewayAccountStatus.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GATEWAY_ACCOUNT_STATUS, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allGatewayAccountStatus;
            }
        });
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_SUPPLIER_GATEWAY_ACCOUNT, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                GatewayAccountQuery query = new GatewayAccountQuery();
                query.setType(GatewayAccountType.SUPPLIER.getCode());
                query.setStatus(GatewayAccountStatus.ENABLED.getCode());
                return gatewayAccountMapper.selectByParam(query);
            }
        });
        allHelpCenterRecordCategory = Arrays.asList(HelpCenterRecordCategory.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_HELP_CENTER_HELP_CATEGORY, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allHelpCenterRecordCategory;
            }
        });
        allHelpCenterRecordStatus = Arrays.asList(HelpCenterRecordStatus.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_HELP_CENTER_HELP_STATUS, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allHelpCenterRecordStatus;
            }
        });
        allGoodsDemandStatus = Arrays.asList(GoodsDemandStatus.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GOODS_DEMAND_STATUS, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allGoodsDemandStatus;
            }
        });
        allGoodsDemandNeedNotice = Arrays.asList(GoodsDemandNeedNotice.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GOODS_DEMAND_NEED_NOTICE, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allGoodsDemandNeedNotice;
            }
        });
        allAccountRechargeChannel = Arrays.asList(AccountRechargeChannel.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_ACCOUNT_RECHARGE_CHANNEL, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allAccountRechargeChannel;
            }
        });
        allAccountRechargeStatus = Arrays.asList(AccountRechargeStatus.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_ACCOUNT_RECHARGE_STATUS, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allAccountRechargeStatus;
            }
        });
        allAccountTransactionCategory = Arrays.asList(AccountTransactionCategory.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_ACCOUNT_TRANSACTION_CATRGORY, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allAccountTransactionCategory;
            }
        });
        allProvince = Arrays.asList(Province.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_PROVINCE, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allProvince;
            }
        });
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_BRAND, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return brandMapper.selectAll();
            }
        });
        allSeason = Arrays.asList(Season.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_SEASON, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allSeason;
            }
        });
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_DELIVERY_TYPE, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return deliveryTypeMapper.selectAll();
            }
        });
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_SUPPLIER_CHANNEL, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return supplierChannelMapper.selectAll();
            }
        });
        allGoodsCategory = Arrays.asList(GoodsCategory.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GOODS_CATEGORY, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allGoodsCategory;
            }
        });
        allGoodsSex = Arrays.asList(GoodsSex.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_GOODS_SEX, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allGoodsSex;
            }
        });
        allCustomerOrderStatus = Arrays.asList(CustomerOrderStatus.values());
        getEnumByCodeHandlerMap.put(EnumDao.ENUM_CUSTOMER_ORDER_STATUS, new Callable<List<?>>() {
            @Override
            public List<?> call() throws Exception {
                return allCustomerOrderStatus;
            }
        });
    }

    public Map<String, List<?>> getEnumByCode(List<String> enumCodes) {
        Map<String, List<?>> result = new HashMap<>();
        List<String> getEnumByDefaultCodeList = new ArrayList<>();
        for (String code : enumCodes) {
            Callable<List<?>> handler = getEnumByCodeHandlerMap.get(code);
            if (handler != null) {
                List<?> list = null;
                try {
                    list = handler.call();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
                if (!CollectionUtils.isEmpty(list)) {
                    result.put(code, list);
                }
            } else {
                getEnumByDefaultCodeList.add(code);
            }
        }
        if (!CollectionUtils.isEmpty(getEnumByDefaultCodeList)) {
            List<CustomDataDictionary> list = dataDictionaryDao.queryByCodes(getEnumByDefaultCodeList);
            for (CustomDataDictionary e : list) {
                String code = e.getCode();
                List<CustomDataDictionary.Detail> contentObject = e.getContentObject();
                if (!CollectionUtils.isEmpty(contentObject)) {
                    Collections.sort(contentObject, new Comparator<CustomDataDictionary.Detail>() {
                        @Override
                        public int compare(CustomDataDictionary.Detail o1, CustomDataDictionary.Detail o2) {
                            return o1.getIndex().compareTo(o2.getIndex());
                        }
                    });
                }
                result.put(code, contentObject);
            }
        }
        return result;
    }

    public List<Brand> getAllBrand() {
        return brandMapper.selectAll();
    }

    public List<DeliveryType> getAllDeliveryType() {
        return deliveryTypeMapper.selectAll();
    }

    public List<SupplierChannel> getAllSupplierChannel() {
        return supplierChannelMapper.selectAll();
    }

}
